package util;

import view.ScanCameraFrame;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

public class LogManager {
    private static final int BATCH_SIZE = 10; // 每次写入的日志条数
    private static final int TIMEOUT = 3; // 超时时间（秒）
    private final BlockingQueue<String> logQueue = new LinkedBlockingQueue<>();
    private final Thread logThread;
    private Path logDir;
    private volatile boolean running = true; // 控制线程运行状态

    // 双重检查锁实现单例模式
    private volatile static LogManager instance;

    public static LogManager getInstance() {
        if (instance == null) {
            synchronized (LogManager.class) {
                if (instance == null) {
                    instance = new LogManager();
                }
            }
        }
        return instance;
    }

    private LogManager() {
        // 初始化日志目录
        try {
            logDir = Paths.get(System.getProperty("user.dir"), "logs");
            Files.createDirectories(logDir);
        } catch (IOException e) {
            System.out.println("日志目录创建失败：" + e.getMessage());
        }

        // 启动日志写入线程
        logThread = new Thread(this::processLogs);
        logThread.start();
    }

    // 日志写入逻辑：批量处理日志，减少 I/O 操作
    private void processLogs() {
        List<String> logBatch = new ArrayList<>(BATCH_SIZE);
        try {
            while (running || !logQueue.isEmpty()) {
                try {
                    // 等待获取日志，批量收集
                    String log = logQueue.poll(TIMEOUT, TimeUnit.SECONDS);
                    if (log != null) {
                        logBatch.add(log);
                    }

                    // 如果达到批量大小或超时，写入文件
                    if (logBatch.size() >= BATCH_SIZE || (!running && !logBatch.isEmpty())) {
                        writeLogsToFile(logBatch);
                        logBatch.clear();
                    }
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    System.out.println("日志线程中断：" + e.getMessage());
                }
            }
        } catch (Exception e) {
            System.out.println("日志写入失败：" + e.getMessage());
        }
    }

    // 将日志批量写入文件
    private void writeLogsToFile(List<String> logs) {
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(logDir.resolve("sdk.log").toString(), true))) {
            for (String log : logs) {
                writer.write(log);
            }
            writer.flush();
        } catch (IOException e) {
            System.out.println("日志文件写入失败：" + e.getMessage());
        }
    }

    // 追加日志到队列
    public void appendLog(String msg) {
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        logQueue.offer("[" + timestamp + "] " + msg + "\n");
    }

    // 追加日志并显示在 UI 面板
    public void appendLog(String msg, ScanCameraFrame cameraFrame) {
        appendLog(msg);
        if (cameraFrame != null) {
            cameraFrame.showBoard(msg);
        }
    }

    // 停止日志线程，确保程序优雅退出
    public void shutdown() {
        running = false;
        try {
            logThread.join();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            System.out.println("日志线程停止失败：" + e.getMessage());
        }
    }
}
